package zm.irc.ioc.pojo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.mysql.cj.util.StringUtils;

import zm.irc.ioc.classCollector.ClassCollector;

public class WrapClass {
    private static final Map<Class<?>,WrapClass> wrapClassPool;
    private static final Map<Class<?>,Set<WrapClass>> childMap;
    static{
        wrapClassPool = new HashMap<>();
        childMap = new HashMap<>();
    }
    private String beanId;
    private boolean isSinglet;
    private Class<?> originClass;
    private String configFileName;
    private boolean isLocalCfg;
    private List<WrapField> autoWriedFields;

    @Override
    public String toString() {
        return this.originClass.toString();
    }

    public static WrapClass build(Class<?> originClass){
        WrapClass clazz = wrapClassPool.get(originClass);
        if(clazz == null){
            clazz = new WrapClass(originClass);
            wrapClassPool.put(originClass, clazz);
        }
        return clazz;
    }


    /**
     * Invoiked by {@link ClassCollector#collecte(String)} 
     */
    public static void initChildMap(){
        for(Entry<Class<?>,WrapClass> entry : wrapClassPool.entrySet()){
            Class<?> clazz = entry.getKey();
            WrapClass wrapClass = entry.getValue();
            Class<?> superClass = clazz.getSuperclass();
            Class<?>[]  interfaces = clazz.getInterfaces();
            if(superClass != null && !superClass.equals(Object.class)){
                Set<WrapClass> child = childMap.computeIfAbsent(superClass, (k)-> new HashSet<>());
                child.add(wrapClass);
    
            }

            
            if(interfaces != null && interfaces.length != 0){
                for(Class<?> itf : interfaces){
                    Set<WrapClass> child = childMap.computeIfAbsent(itf, (k)-> new HashSet<>());
                    child.add(wrapClass);
                }
            }

          
        }
    }


    public static Set<WrapClass> getByType(Class<?> superClass){
        return childMap.get(superClass);
    }

    private WrapClass(Class<?> originClass){
        this.originClass = originClass;
        this.autoWriedFields = new ArrayList<>();
    }

    public void setCfgFileName(String cfgFileName){
        this.configFileName = cfgFileName;
    }

    public String getCfgFileName(){
        return this.configFileName;
    }
    

    public boolean isLocalCfg() {
        return isLocalCfg;
    }

    public void setLocalCfg(boolean isLocalCfg) {
        this.isLocalCfg = isLocalCfg;
    }

    public boolean isSinglet(){
        return this.isSinglet;
    }

    public void setSinglet(boolean isSinglet){
        this.isSinglet = isSinglet;
    }

    public String getBeanId() {
        return StringUtils.isEmptyOrWhitespaceOnly(beanId)  ? this.getOriginClass().getName(): beanId;
    }

    public void setBeanId(String beanId) {
        this.beanId = beanId;
    }


    public Class<?> getOriginClass(){
        return this.originClass;
    }

    public List<WrapField> getAutoWiredFields(){
        return this.autoWriedFields;
    }

    public void addAutoWiredField(WrapField autoWiredField){
        if( autoWiredField == null){
            return;
        }
        this.autoWriedFields.add(autoWiredField);
    }
}
